/*
 * JBeagle - a Java toolkit for genetic algorithms.
 * 
 * Copyright (c) 2010 Matthijs Snel
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package jbeagle.core;

import java.util.Collection;
import java.util.Random;

public abstract class ListIndividualFactory<G> implements IndividualFactory<ListIndividual<G>, G> {
	
	protected int minlen, maxlen;
	protected Constraints<G> constr;
	protected Random rand;
	
	public ListIndividualFactory( int minlen, int maxlen ) {
		setRNG(new Random( System.currentTimeMillis() ));
		setMinimumLength(minlen);
		setMaximumLength(maxlen);
	}
	
	public void setRNG(Random rng) {
		rand = rng;
	}
	
	public ListIndividual<G> createIndividual() {
		int len = generateLength();
		ListIndividual<G> ind = new ListIndividual<G>( len );
		fillIndividual(ind, len);
        ind.setConstraints(constr);
		return ind;
	}
	
	public ListIndividual<G> createIndividual( Collection<String> values ) {
		ListIndividual<G> ind = new ListIndividual<G>( values.size() );
		fillIndividual(ind, values);
        ind.setConstraints(constr);
		return ind;
	}
	
	public void setConstraints(Constraints<G> constr) {
        this.constr = constr;
    }
	
	public void setMinimumLength(int minLength) {
		minlen = minLength;
	}
	
	public void setMaximumLength(int maxLength) {
		maxlen = maxLength;
	}
	
	protected abstract void fillIndividual( ListIndividual<G> ind, int len);
	
	protected abstract void fillIndividual( ListIndividual<G> ind, Collection<String> values);
	
	protected int generateLength() {
		return (minlen + rand.nextInt(maxlen + 1 - minlen));
	}
}
